<?php

//require_once 'PHPUnit/Framework/Assert/Functions.php';
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

class Lib_TestBase extends PHPUnit_Framework_TestCase
{
    public $reflectionClass;
    protected $mockedClasses;

    public function getMethod($name)
    {
        if(!$this->reflectionClass)
            $this->reflectionClass = new ReflectionClass($this->classUnderTest);
        $method = $this->reflectionClass->getMethod($name);
        $method->setAccessible(true);
        return $method;
    }

    public static function getMethodOf($class, $name)
    {
        $reflectionClass = new ReflectionClass($class);
        $method = $reflectionClass->getMethod($name);
        $method->setAccessible(true);
        return $method;
    }

    public function __callMethod($name, $arguments = array())
    {
        $method = self::getMethod($name);
        return $method->invokeArgs($this->classUnderTest, $arguments);
    }

    public static function __callMethodOf($class, $name, $arguments = array())
    {
        $method = self::getMethodOf($class, $name);
        return $method->invokeArgs($class, $arguments);
    }
    
    /**
     * Callback implementation that passes static method calls
     * to native functions of equal names and returns whatever they return.
     *
     * Function names may optionally be prefixed with nativeFunction_
     * to work around restricted names.
     *
     * @param $name function to call optionally prefixed with nativeFunction_
     * @param $arguments whatever the function was called with
     * @return whatever the called function returns.
     */
    public static function __callStatic($name, $arguments)
    {
        $name = preg_replace('/^nativeFunction_/', '', $name);
        return call_user_func_array($name, $arguments);
    }

    public function mockClasses($listOfClasses)
    {
        foreach($listOfClasses as $className)
            $this->mockClass($className);
    }
    public function mockClass($className, $constants = array())
    {
        //class_exists($className) || CallFlow::mockClass($className);
        if(isset($this->mockedClasses[$className]))
                throw new Exception("Class $className already mocked!");
        else
            CallFlow::mockClass($className, $constants);
        $this->mockedClasses[$className] = true;
    }

    protected function fakeHttpRequest($request)
    {
        $_SERVER['REQUEST_URI'] = $request;
    }

    protected function fakeConsoleRequest($request)
    {
        global $argv;
        $argv = explode(' ', $request);
    }

}